﻿#include "srcQGraphicsView.h"
#include <QOpenGLWidget>
#include <QtOpenGL/QGLWidget>

srcQGraphicsView::srcQGraphicsView(QWidget *parent) :
    QGraphicsView(parent)
{
    //标记独立点（0），标记连续点（1），测量距离（2），选取ROI（3），拖拽模式（4），读像素值（5），标记ROI（16），
    state = state&0X0000;

	rect = nullptr;
	line = nullptr;
	pixm = nullptr;

    pen.setStyle(Qt::DashLine);
    pen.setWidth(2);
    pen.setBrush(Qt::blue);
    pen.setCapStyle(Qt::SquareCap);
    pen.setJoinStyle(Qt::MiterJoin);
//    connect(this,SIGNAL(rightButtonDown(QPointF)),this,SLOT(viewMenu( QPointF)));

	//setViewport(new QOpenGLWidget);
	setCacheMode(QGraphicsView::CacheNone);
	setViewport(new QGLWidget);
}

void srcQGraphicsView::mousePressEvent(QMouseEvent *event)
{
    QGraphicsView::mousePressEvent(event);
    if(event->buttons()==Qt::LeftButton )
    {
        switch(state)
        {
        case 0X0001: //标记独立点
            C_point.push_back(scene()->addLine(QLineF(mapToScene(event->pos()),mapToScene(event->pos())),QPen(Qt::red, 3, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin)));
            C_points.push_back(mapToScene(event->pos()));
            emit leftButtonDown(mapToScene(event->pos()));
            break;
        case 0X0002:  //标记连续点
            C_points.clear();
            C_points.push_back(mapToScene(event->pos()));
            break;
        case 0X0004:
        case 0X0008:
            emit leftButtonDown(mapToScene(event->pos()));
            break;
        }
    }
    else if(event->button()==Qt::RightButton)//如果在presss事件中创建菜单会导致rreleases事件没反应
    {
        emit viewMenu(mapToScene(event->pos()));
    }
}

void srcQGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    QGraphicsView::mouseMoveEvent(event);
    if(event->buttons()==Qt::LeftButton )
    {
        state|=0X0200;  //设置左键移动标志(17)
        switch(state)
        {
        case 0X0201: //标记独立点
            break;
        case 0X0202:  //标记连续点
            C_points.push_back(mapToScene(event->pos()));
            C_line.push_back(scene()->addLine(QLineF(C_points[C_points.size()-2], C_points[C_points.size()-1]),QPen(Qt::green, 3, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin)));
            emit leftButtonDown(mapToScene(event->pos()));
            break;
        case 0X0204:
        case 0X0208:
            emit mousePressMove(mapToScene(event->pos()));
            break;
        case 0X0210:
            break;
        case 0X0220:
            emit mouseMove(mapToScene(event->pos()));
            break;
        }
    }
}

void srcQGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    QGraphicsView::mouseReleaseEvent(event);
    if(event->buttons()==Qt::NoButton && state&0X0200)
    {
        state&=0XFDFF; //取消左键移动标志(17)
        switch(state)
        {
        case 0X0001: //标记独立点
            break;
        case 0X0002://标记连续点
            C_points.push_back(mapToScene(event->pos()));
            C_line.push_back(scene()->addLine(QLineF(C_points[C_points.size()-2], C_points[C_points.size()-1]),QPen(Qt::green, 3, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin)));
            if(C_points.size()>2)
                C_pointsVec.push_back(C_points);
            C_points.clear();
            break;
        case 0X0004:
        case 0X0008:
            emit leftButtonUp(mapToScene(event->pos()));
            break;
        }
    }
}

void srcQGraphicsView::viewMenu(QPointF pos)
{
        rightMenu.clear();
        QAction *action1 = new QAction( QString::fromStdWString(L"标记独立点"), this);
        action1->setCheckable(true);
        if(state&0X0001)
            action1->setChecked(true);
        else
            action1->setChecked(false);
        connect(action1, SIGNAL(triggered()), this, SLOT(addPoint()));
        rightMenu.addAction(action1);

        QAction *action2 = new QAction( QString::fromStdWString(L"标记连续点"), this);
        action2->setCheckable(true);
        if(state&0X0002)
            action2->setChecked(true);
        else
            action2->setChecked(false);
        connect(action2, SIGNAL(triggered()), this, SLOT(addPoints()));
        rightMenu.addAction(action2);

        QAction *action3 = new QAction( QString::fromStdWString(L"测量距离"), this);
        action3->setCheckable(true);
        if(state&0X0004)
        {
            action3->setChecked(true);
        }
        else
        {
            action3->setChecked(false);
            setDragMode(QGraphicsView::RubberBandDrag);
            if(line!=0) /*删除有可能存在的线*/
            {
                scene()->removeItem((QGraphicsItem *)this->line);
                line = 0;
            }
        }
        connect(action3, SIGNAL(triggered()), this, SLOT(disMod()));
        rightMenu.addAction(action3);

        QAction *action4 = new QAction( QString::fromStdWString(L"选取ROI"), this);
        action4->setCheckable(true);
        if(state&0X0008)
            action4->setChecked(true);
        else
            action4->setChecked(false);
        connect(action4, SIGNAL(triggered()), this, SLOT(roiMod()));
        rightMenu.addAction(action4);

        QAction *action5 = new QAction( QString::fromStdWString(L"拖拽模式"), this);
        action5->setCheckable(true);
        if(state&0X0010)
            action5->setChecked(true);
        else
            action5->setChecked(false);
        connect(action5, SIGNAL(triggered()), this, SLOT(dragMod()));
        rightMenu.addAction(action5);

        QAction *action6 = new QAction( QString::fromStdWString(L"读取像素值"), this);
        action6->setCheckable(true);
        if(state&0X0020)
            action6->setChecked(true);
        else
            action6->setChecked(false);
        connect(action6, SIGNAL(triggered()), this, SLOT(readMod()));
        rightMenu.addAction(action6);

        QAction *action7 = new QAction( QString::fromStdWString(L"清空标记的点"), this);
        action7->setCheckable(true);
        if(state&0X0040)
            action7->setChecked(true);
        else
            action7->setChecked(false);
        connect(action7, SIGNAL(triggered()), this, SLOT(clearPoints()));
        rightMenu.addAction(action7);

        QAction *action8 = new QAction( QString::fromStdWString(L"显示ROI"), this);
        action8->setCheckable(true);
        if(state&0X0100)
            action8->setChecked(true);
        else
            action8->setChecked(false);
        connect(action8, SIGNAL(triggered()), this, SLOT(drawRoi()));
        rightMenu.addAction(action8);

        rightMenu.popup(this->mapToGlobal(QGraphicsView::mapFromScene(pos)));
//    QMenu *rightMenu = new QMenu(this);
//    rightMenu->setAttribute(Qt::WA_DeleteOnClose);

//    QAction *action1 = new QAction( tr("标记独立点"), this);
//    action1->setCheckable(true);
//    if(state&0X0001)
//        action1->setChecked(true);
//    else
//        action1->setChecked(false);
//    connect(action1, SIGNAL(triggered()), this, SLOT(addPoint()));
//    rightMenu->addAction(action1);

//    QAction *action2 = new QAction( tr("标记连续点"), this);
//    action2->setCheckable(true);
//    if(state&0X0002)
//        action2->setChecked(true);
//    else
//        action2->setChecked(false);
//    connect(action2, SIGNAL(triggered()), this, SLOT(addPoints()));
//    rightMenu->addAction(action2);

//    QAction *action3 = new QAction( tr("测量距离"), this);
//    action3->setCheckable(true);
//    if(state&0X0004)
//    {
//        action3->setChecked(true);
//    }
//    else
//    {
//        action3->setChecked(false);
//        setDragMode(QGraphicsView::RubberBandDrag);
//        if(line!=0) /*删除有可能存在的线*/
//        {
//            scene()->removeItem((QGraphicsItem *)this->line);
//            line = 0;
//        }
//    }
//    connect(action3, SIGNAL(triggered()), this, SLOT(disMod()));
//    rightMenu->addAction(action3);

//    QAction *action4 = new QAction( tr("选取ROI"), this);
//    action4->setCheckable(true);
//    if(state&0X0008)
//        action4->setChecked(true);
//    else
//        action4->setChecked(false);
//    connect(action4, SIGNAL(triggered()), this, SLOT(roiMod()));
//    rightMenu->addAction(action4);

//    QAction *action5 = new QAction( tr("拖拽模式"), this);
//    action5->setCheckable(true);
//    if(state&0X0010)
//        action5->setChecked(true);
//    else
//        action5->setChecked(false);
//    connect(action5, SIGNAL(triggered()), this, SLOT(dragMod()));
//    rightMenu->addAction(action5);

//    QAction *action6 = new QAction( tr("读取像素值"), this);
//    action6->setCheckable(true);
//    if(state&0X0020)
//        action6->setChecked(true);
//    else
//        action6->setChecked(false);
//    connect(action6, SIGNAL(triggered()), this, SLOT(readMod()));
//    rightMenu->addAction(action6);

//    QAction *action7 = new QAction( tr("清空标记的点"), this);
//    action7->setCheckable(true);
//    if(state&0X0040)
//        action7->setChecked(true);
//    else
//        action7->setChecked(false);
//    connect(action7, SIGNAL(triggered()), this, SLOT(clearPoints()));
//    rightMenu->addAction(action7);

//    QAction *action8 = new QAction( tr("显示ROI"), this);
//    action8->setCheckable(true);
//    if(state&0X0100)
//        action8->setChecked(true);
//    else
//        action8->setChecked(false);
//    connect(action8, SIGNAL(triggered()), this, SLOT(drawRoi()));
//    rightMenu->addAction(action8);

//    rightMenu->popup(this->mapToGlobal(QGraphicsView::mapFromScene(pos)));
}

void srcQGraphicsView::addPoint()
{
    //标记独立点（0）
    if(!(state&0X0001))
    {
        state = state&0XFF00;
        state = state|0X0001;
        C_points.clear();
    }
    else
        state = state&0XFF00;
}

void srcQGraphicsView::addPoints()
{
    //标记连续点（1）
    if(!(state&0X0002))
    {
        state = state&0XFF00;
        state = state|0X0002;
        C_points.clear();
        C_pointsVec.clear();
    }
    else
        state = state&0XFF00;
}

void srcQGraphicsView::disMod()
{
    //测量距离（2）
    if(!(state&0X0004))
    {
        this->setDragMode(QGraphicsView::NoDrag);
        state = state&0XFF00;
        state = state|0X0004;
    }
    else
    {
        if(line!=0) /*删除有可能存在的线*/
        {
            scene()->removeItem((QGraphicsItem *)this->line);
            line = 0;
        }
        state = state&0XFF00;
    }
}

void srcQGraphicsView::roiMod()
{
    //选取ROI（3）
    if(!(state&0X0008))
    {
        state = state&0XFF00;
        state = state|0X0008;
    }
    else
        state = state&0XFF00;
}

void srcQGraphicsView::dragMod()
{
    //拖拽模式（4）
    if(!(state&0X0010))
    {
        state = state&0XFF00;
        state = state|0X0010;
        this->setDragMode(QGraphicsView::ScrollHandDrag);
    }
    else
    {
        state = state&0XFF00;
        this->setDragMode(QGraphicsView::RubberBandDrag);
    }
}

void srcQGraphicsView::readMod()
{
    //读取像素值（5）
    if(!(state&0X0020))
    {
        state = state&0XFF00;
        state = state|0X0020;
    }
    else
        state = state&0XFF00;
}

void srcQGraphicsView::clearPoints()
{
    if(QMessageBox::question(0,QString::fromStdWString(L"确认操作"),QString::fromStdWString(L"是否清空标记的所有点？"),
		QMessageBox::Ok,QMessageBox::Cancel) == QMessageBox::Ok)
    {
        QList<QGraphicsLineItem *>::Iterator it;
        for(it=C_point.begin(); it!=C_point.end(); it++)
            scene()->removeItem((QGraphicsItem *)*it);
        for(it=C_line.begin(); it!=C_line.end(); it++)
            scene()->removeItem((QGraphicsItem *)*it);
        C_point.clear();
        C_line.clear();
        C_points.clear();
        C_pointsVec.clear();
    }
}

void srcQGraphicsView::drawRoi()
{
    //显示ROI（16）
    if(!(state&0X0100))
    {
        state = state&0X00FF;
        state = state|0X0100;
    }
    else
        state = state&0X00FF;
    emit showRect();
}

#include "moc_srcQGraphicsView.cpp"